package com.hotelsystem.reservations.clientvalidation;

import java.util.ArrayList;

import com.hotelsystem.reservations.persons.Client;
import com.hotelsystem.reservations.persons.ClientManagement;

/**
 * Validates the client object properties
 * 
 * @author Qni & others
 */
public class ClientValidation {

	/**
	 * Validates the email of the clien t
	 * <p/>
	 * Should have single @ and one . after it. Should not end in .
	 * 
	 * @param email
	 *            to validate
	 * @return whether the email is valid
	 */

	public boolean isValidEmail(String email) {
		String emailPattern = "^[\\w+\\.+\\_+\\-]+@[(a-z-A-Z)]+\\.[(a-z-A-Z)]{2,4}$";
		return email.matches(emailPattern);
	}

	/**
	 * Validate client name: name start with uppercase, should be only
	 * characters and " ' " and " - " but not at the end of name
	 * 
	 * @param firstName
	 *            Validate first name
	 * @param lastName
	 *            Validate last name
	 * @return True or False
	 */
	public boolean isValidName(String firstName, String lastName) {
		String pattern = "[A-Z]([A-Za-z]|([-][a-zA-Z])|('[a-zA-Z]))+";
		return firstName.matches(pattern) && lastName.matches(pattern);

	}

	/**
	 * Checks if the length of the string is equal to the required and if it
	 * contains integers
	 * 
	 * @author Nikolai
	 * @return true if everything is okay
	 */
	public boolean isValidId(String str) {
		return str.matches("[0-9]{10}");

	}

	/**
	 * The validation of first and last name of client by Dmitriy
	 * 
	 * @param
	 * @return True, if FirstName and LastName contain alphabet symbols and ',
	 *         false otherwise
	 * @author Dmitriy
	 */
	public boolean namesValidByDmitriy(String firstName, String lastName) {
		// The Regular expression
		String nameRegex = "([A-Z])((['-][A-Z])?[a-z]*)+";
		// the validation
		return (firstName.matches(nameRegex) && lastName.matches(nameRegex));
	}

	/**
	 * /** Phone number should match the 0XXX-XX-XX-XX format
	 * 
	 * @param telephone
	 * @return whether phone number is valid
	 */
	public boolean isTelephoneValid(String telephone) {
		String pattern = "^0\\d{3}-\\d{2}-\\d{2}-\\d{2}$";
		return telephone.matches(pattern);
	}

	/**
	 * Validates the age of the client
	 * 
	 * @param age
	 *            to validate
	 * @return whether the age is valid
	 */
	public boolean isValidAge(String age) {
		int ageNumber;

		try {
			ageNumber = Integer.parseInt(age);

		} catch (NumberFormatException nfe) {
			return false;
		}

		return ageNumber >= 0 && ageNumber <= 120;
	}

	/**
	 * Validate Name Uniquness in the client list
	 * 
	 * @param firstName
	 *            to validate
	 * @param lastName
	 *            to validate
	 * @param clientsList
	 *            list of the clients
	 * @return whether the name is unique
	 */
	public boolean validateNameUniqueness(String firstName, String lastName, ArrayList<Client> clientsList) {

		for (Client theClient : clientsList) {

			if (theClient.getFirstName().equalsIgnoreCase(firstName)
					&& theClient.getLastName().equalsIgnoreCase(lastName)) {
				return false;
			}
		}
		return true;
	}

	public String validateClient(Client client) {
		ClientManagement clientManagement = new ClientManagement();
		StringBuilder errorMessage = new StringBuilder();

		String firstName = validateString(
				"First name must start with uppercase, should be only characters and \" ' \" and \" - \" but not start or ends with these and first and last names must be unique\n",
				isValidName(client.getFirstName(), client.getFirstName()));
		String lastName = validateString(
				"Last name must start with uppercase, should be only characters and \" ' \" and \" - \" but not start or ends with these and first and last names must be unique\n",
				validateNameUniqueness(client.getFirstName(), client.getLastName(), clientManagement.getClients())
						&& isValidName(client.getLastName(), client.getLastName()));
		String personalID = validateString("Personal ID", isValidId(client.getPersonalId()));
		String telephone = validateString("Telephone Number should look like 0XXX-XX-XX-XX\n",
				isTelephoneValid(client.getTelephone()));
		String age = validateString("Age must be between 0 and 120\n", isValidAge(client.getAge() + ""));
		String email = validateString("Email should have single @ and one . after it. Should not end with .\n",
				isValidEmail(client.getEmail()));

		errorMessage.append(firstName);
		errorMessage.append(lastName);
		errorMessage.append(personalID);
		errorMessage.append(telephone);
		errorMessage.append(age);
		errorMessage.append(email);
		return errorMessage.toString().trim();
	}

	/**
	 * 
	 * @param message
	 *            The error message
	 *
	 * @param validatorFunction
	 *            function to validate the input
	 * @return
	 */
	public String validateString(String message, boolean validatorFunction) {

		if (validatorFunction) {
			return "";
		} else {
			return message;
		}

	}

}
